package at.fhooe.mc.msports.heartrate;

import java.io.IOException;
import java.io.InputStream;

import at.fhooe.mc.utils.Utils;


/**
 * Data parser for Zephyr devices.<br />
 * Basically, two methods are providing the main functionality of the parser.
 * <ul>
 * <li>readPacket(InputStream)</li>
 * <li>parsePacket(byte[])</li>
 * </ul>
 * <p>
 * The readPacket method reads a Zephyr bluetooth packet from a given input
 * stream and returns it as a byte array.<br />
 * The parsePacket method parses a given byte array and returns the data
 * represented in a HeartRateData object.
 * </p>
 * 
 * @author Robert Schenkenfelder
 * 
 */
public class ZephyrHeartRateDataParser{

    /**
     * Reads a Zephyr bluetooth packet from a given input stream and returns it
     * as a byte array.
     */
    public byte[] readPacket(InputStream stream) throws IOException {
	if (stream == null) {
	    return null;
	}

	byte[] packet;
	int stx = -1;
	do {
	    // read one character from the serial data flow - read first byte
	    // find good start (STX) for a HxM data packet
	    stx = stream.read();
	} while (stx != 0x02);

	int msgId = stream.read();
	if (msgId != 0x26) {
	    // message type indicates that packet is not a Hxm message
	    return null;
	}

	int dlc = stream.read();

	if (dlc < 0 || dlc > 128) {
	    // length of data payload is out of valid range
	    return null;
	}

	packet = new byte[dlc];
	int byteCount = stream.read(packet);

	if (byteCount != dlc) {
	    // expected length of data payload doesn't match with actual length
	    return null;
	}

	int crc = stream.read();

	if (crc != Utils.calcCRC(packet)) {
	    // crc is not correct
	    return null;
	}

	int etx = stream.read();

	if (etx != 0x03) {
	    // end of text value is not correct
	    return null;
	}

	return packet;
    }

    /**
     * Parses a given byte array and returns the data represented in a
     * HeartRateData object.
     */
    public RawHeartRateData parsePacket(byte[] packet) throws IOException {
	ZephyrHeartRateData data = new ZephyrHeartRateData();

	data.setBatteryStatus(packet[8] & 0xFF);
	data.setHeartRate(packet[9] & 0xFF);

	int rr1L = packet[11] & 0xFF;
	int rr1H = packet[12] & 0xFF;
	int rr = 256 * rr1H + rr1L;
	data.setRR(rr);

	return data;
    }
}
